//
//  THSideDragView.m
//  MengLiao
//
//  Created by xiuxin on 2022/7/15.
//  Copyright © 2022 BaseBusiness. All rights reserved.
//

#import "THSideDragView.h"
#import "UIView+Frame.h"
#import "UIViewController+THCurretnVC.h"
#import <CoreGraphics/CGGeometry.h>
#import "UIView+THAddForRoundedCorner.h"
#import "THCurrentVCWindowsManager.h"

static CGFloat HQSideDragRange = 32.0f;

static UIColor * HQSideDragSafeAreaBottomColor = nil;

@interface THSideDragView()<UIGestureRecognizerDelegate>

@property (nonatomic) CGFloat showAmount;

@property (nonatomic) CGFloat extraDragAmount;

@property (nonatomic) CGFloat contentAmount;

@property (strong,nonatomic) UIView * alphaView;

//@property (strong,nonatomic) UIView * blurView;

@property (nonatomic) CGSize contentSize;

@property (nonatomic,getter = isDragging) BOOL dragging;

@property (strong,nonatomic) UIPanGestureRecognizer * panGesture;

@property (nonatomic) CGRect invalidPanArea;

@property (strong,nonatomic) UIPanGestureRecognizer * displayGesture;

@property (nonatomic) CGFloat dragStartDistance;

@property (nonatomic) BOOL enableDrag;

@property (strong,nonatomic) UIView * bottomSafeAreaView;

@property (strong,nonatomic) UIColor * safeBottomColor;

@end

@implementation THSideDragView

{
    BOOL _hideByGesture;
}

+ (void)setSafeAreaBottomColor:(UIColor *)color
{
    HQSideDragSafeAreaBottomColor = color;
}

- (void)setSafeAreaBottomColor:(UIColor *)color
{
    self.safeBottomColor = color;
    self.bottomSafeAreaView.backgroundColor = self.safeAreaBottomColor;
}

- (UIColor *)safeAreaBottomColor
{
    return self.safeBottomColor ?: HQSideDragSafeAreaBottomColor;
}

- (instancetype)initWithCustomizeView:(UIView *)view position:(THSidePosition)position noSafeArea:(BOOL)noSafeArea
{
    if (self = [super initWithFrame:[UIScreen mainScreen].bounds])
    {
        _displayFrame = self.frame;
        _displayView = [THCurrentVCWindowsManager shareManager].currentWindow;
        _customizeView = view;
        _position = position;
        _safeAreaInsetsBottom = noSafeArea ? 0 : kSafeAeraHeight;
        _enableTapGesture = YES;
        _enablePanGesture = YES;
        [self createUI];
        [self updateConstrants];
        [self configContentSize];
        [self configGesture];
    }
    return self;
}

- (instancetype)initWithCustomizeView:(UIView *)view position:(THSidePosition)position
{
    if (self = [super initWithFrame:[UIScreen mainScreen].bounds])
    {
        _displayFrame = self.frame;
        _displayView = [THCurrentVCWindowsManager shareManager].currentWindow;
        _customizeView = view;
        _position = position;
        _safeAreaInsetsBottom = kSafeAeraHeight;
        _enableTapGesture = YES;
        _enablePanGesture = YES;
        [self createUI];
        [self updateConstrants];
        [self configContentSize];
        [self configGesture];
    }
    return self;
}

- (void)configContentSize
{
    if (self.position == THSidePositionTop || self.position == THSidePositionBottom)
    {
        [_customizeView stayIntrinsicWidth];
    }
    else
    {
        [_customizeView stayIntrinsicHeight];
    }
    _contentSize = [_customizeView compressedSize];
    _contentSize.height += self.safeAreaInsetsBottom;
    if (self.position == THSidePositionTop || self.position == THSidePositionBottom)
    {
        _extraDragAmount = (CGRectGetHeight(self.displayFrame) - _contentSize.height) / 2;
         _contentSize.width = CGRectGetWidth(self.displayFrame);
        _contentAmount = _contentSize.height;
    }
    else
    {
        _extraDragAmount = (CGRectGetWidth(self.displayFrame) - _contentSize.width) / 2;
         _contentSize.height = CGRectGetHeight(self.displayFrame);
        _contentAmount = _contentSize.width;
    }
     CGRect invalidPanArea = CGRectMake(0, 0, _contentSize.width, _contentSize.height);
     if (self.position == THSidePositionTop || self.position == THSidePositionBottom)
     {
          invalidPanArea.size.height -= HQSideDragRange;
          if (self.position == THSidePositionBottom)
          {
               invalidPanArea.origin.y = HQSideDragRange;
          }
     }
     else
     {
          invalidPanArea.size.width -= HQSideDragRange;
          if (self.position == THSidePositionRight)
          {
               invalidPanArea.origin.x = HQSideDragRange;
          }
     }
     self.invalidPanArea = invalidPanArea;
}

- (void)createUI
{
    _alphaView = [[UIView alloc] initWithFrame:self.bounds];
    _alphaView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:.7];
    _alphaView.alpha = 0;
    
    if (@available(iOS 9.0, *))
    {
        _blurView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight]];
    }
    else
    {
        _blurView = [UIView new];
        _blurView.backgroundColor = [UIColor whiteColor];
    }
    
    _contentView = [UIView new];
    _contentView.backgroundColor = _customizeView.backgroundColor;
    [_contentView addSubview:_customizeView];
    
    [self addSubview:_alphaView];
    [self addSubview:_blurView];
    [self addSubview:_contentView];
    if (self.safeAreaInsetsBottom > 0 && self.position != THSidePositionTop)
    {
        _bottomSafeAreaView = [UIView new];
        _bottomSafeAreaView.backgroundColor = self.safeAreaBottomColor;
        if (self.position == THSidePositionRight)
        {
            [self.contentView addSubview:_bottomSafeAreaView];
        }
        else
        {
            [self addSubview:_bottomSafeAreaView];
        }
    }
    
    _blurView.hidden = _customizeView.backgroundColor?YES:NO;
//    _customizeView.backgroundColor && ![_customizeView.backgroundColor isEqual:[UIColor clearColor]];
}

- (void)configGesture
{
    UIGestureRecognizer * gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapRecgnized:)];
    [_alphaView addGestureRecognizer:gesture];
    
    UIPanGestureRecognizer * panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panRecgnized:)];
    panGesture.maximumNumberOfTouches = 1;
    [self addGestureRecognizer:panGesture];
    
    [gesture requireGestureRecognizerToFail:panGesture];
     
     self.panGesture = panGesture;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
     return !CGRectContainsPoint(self.invalidPanArea, [touch locationInView:self.contentView]);
}

- (void)setPreventGestureConflict:(BOOL)preventGestureConflict
{
     if (_preventGestureConflict != preventGestureConflict)
     {
          _preventGestureConflict = preventGestureConflict;
          self.panGesture.delegate = preventGestureConflict ? self : nil;
     }
}

- (void)setCanDragOut:(BOOL)canDragOut
{
    if (_canDragOut != canDragOut)
    {
        _canDragOut = canDragOut;
        if (canDragOut)
        {
            self.displayGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(displayViewPanRecgnized:)];
            _displayGesture.maximumNumberOfTouches = 1;
            _displayGesture.delegate = self;
            [self.displayView addGestureRecognizer:_displayGesture];
            UIGestureRecognizer * popGesture = [UIViewController currentNavigationController].interactivePopGestureRecognizer;
            if (popGesture)
            {
                [_displayGesture requireGestureRecognizerToFail:popGesture];
            }
        }
        else if (self.displayGesture)
        {
            [self.displayView removeGestureRecognizer:self.displayGesture];
            self.displayGesture = nil;
        }
    }
}

- (void)updateConstrants
{
    [self mas_updateConstraints:^(MASConstraintMaker *make) {
        if (self.superview)
        {
            make.left.top.mas_equalTo(0);
        }
        make.width.mas_equalTo(CGRectGetWidth(self.displayFrame));
        make.height.mas_equalTo(CGRectGetHeight(self.displayFrame));
    }];
    
    [_alphaView mas_updateConstraints:^(MASConstraintMaker *make) {
        if (self.position == THSidePositionTop)
        {
            make.bottom.mas_equalTo(0);
            make.left.right.mas_equalTo(0);
        }
        else if (self.position == THSidePositionBottom)
        {
            make.top.mas_equalTo(0);
            make.left.right.mas_equalTo(0);
        }
        else if (self.position == THSidePositionLeft)
        {
            make.right.mas_equalTo(0);
            make.top.bottom.mas_equalTo(0);
        }
        else
        {
            make.left.mas_equalTo(0);
            make.top.bottom.mas_equalTo(0);
        }
    }];
    
    [_contentView mas_updateConstraints:^(MASConstraintMaker *make) {
        if (self.position == THSidePositionTop)
        {
            make.top.mas_equalTo(0);
            make.left.right.mas_equalTo(0);
            make.bottom.mas_equalTo(self.alphaView.mas_top).offset(_blurView.isHidden ? KRelative(40) : 0.0f);;
        }
        else if (self.position == THSidePositionBottom)
        {
            make.left.right.mas_equalTo(0);
            make.top.mas_equalTo(self.alphaView.mas_bottom).offset(_blurView.isHidden ? -KRelative(40) : 0.0f);
        }
        else if (self.position == THSidePositionLeft)
        {
            make.left.mas_equalTo(0);
            make.top.mas_equalTo(0);
            make.right.mas_equalTo(self.alphaView.mas_left).offset(_blurView.isHidden ? KRelative(40) : 0.0f);
        }
        else
        {
            make.right.mas_equalTo(0);
            make.top.mas_equalTo(0);
            make.left.mas_equalTo(self.alphaView.mas_right).offset(_blurView.isHidden ? -KRelative(40) : 0.0f);
        }
        
        if (self.position == THSidePositionRight)
        {
            make.bottom.mas_equalTo(0);
        }
        else if (self.position != THSidePositionTop)
        {
            make.bottom.mas_equalTo(-self.safeAreaInsetsBottom);
        }
    }];
    
    [_blurView mas_updateConstraints:^(MASConstraintMaker *make) {
        if (self.position == THSidePositionTop)
        {
            make.bottom.mas_equalTo(self.contentView);
            make.left.right.mas_equalTo(0);
            make.height.mas_equalTo(CGRectGetHeight(self.displayFrame));
        }
        else if (self.position == THSidePositionBottom)
        {
            make.top.mas_equalTo(self.contentView);
            make.left.right.mas_equalTo(0);
            make.height.mas_equalTo(CGRectGetHeight(self.displayFrame));
        }
        else if (self.position == THSidePositionLeft)
        {
            make.right.mas_equalTo(self.contentView);
            make.top.mas_equalTo(0);
            make.bottom.mas_equalTo(0);
            make.width.mas_equalTo(CGRectGetWidth(self.displayFrame));
        }
        else
        {
            make.left.mas_equalTo(self.contentView);
            make.top.mas_equalTo(0);
            make.bottom.mas_equalTo(0);
            make.width.mas_equalTo(CGRectGetWidth(self.displayFrame));
        }
    }];
    
    [_bottomSafeAreaView mas_updateConstraints:^(MASConstraintMaker *make) {
        if (self.position == THSidePositionLeft)
        {
            make.right.mas_equalTo(self.contentView);
            make.height.mas_equalTo(self.safeAreaInsetsBottom);
        }
        else if (self.position == THSidePositionRight)
        {
            make.left.mas_equalTo(self.contentView);
            make.height.mas_equalTo(self.safeAreaInsetsBottom);
        }
        else
        {
            make.left.right.mas_equalTo(0);
        }
        make.bottom.mas_equalTo(0);
    }];
    
    [self updateCustomeViewConstraints];
    [self updateShowAmountConstraints];
    [super updateConstraints];
}

- (void)updateCustomeViewConstraints
{
    [_customizeView mas_updateConstraints:^(MASConstraintMaker *make) {
        if (self.position == THSidePositionTop)
        {
            make.bottom.mas_equalTo(self.contentView);
            make.centerX.mas_equalTo(self.contentView);
            make.width.mas_equalTo(self.contentView);
        }
        else if (self.position == THSidePositionBottom)
        {
            make.top.mas_equalTo(self.contentView);
            make.centerX.mas_equalTo(self.contentView);
            make.width.mas_equalTo(self.contentView);
        }
        else if (self.position == THSidePositionLeft)
        {
            make.right.mas_equalTo(self.contentView);
            make.centerY.mas_equalTo(self.contentView);
            make.height.mas_equalTo(self.contentView);
        }
        else if (self.position == THSidePositionRight)
        {
            make.left.mas_equalTo(self.contentView);
            make.centerY.mas_equalTo(self.contentView);
            make.bottom.mas_equalTo(-self.safeAreaInsetsBottom);
        }
    }];
}

- (void)updateShowAmountConstraints
{
    [_contentView mas_updateConstraints:^(MASConstraintMaker *make) {
        if (self.position == THSidePositionTop)
        {
            make.bottom.mas_equalTo(-(CGRectGetHeight(self.displayFrame) - self.showAmount));
        }
        else if (self.position == THSidePositionBottom)
        {
            make.top.mas_equalTo(CGRectGetHeight(self.displayFrame) - self.showAmount);
            if (self.showAmount <= self.safeAreaInsetsBottom)
            {
                make.bottom.mas_equalTo(-self.showAmount);
            }
            else
            {
                make.bottom.mas_equalTo(-self.safeAreaInsetsBottom);
            }
        }
        else if (self.position == THSidePositionLeft)
        {
            make.right.mas_equalTo(-(CGRectGetWidth(self.displayFrame) - self.showAmount));
        }
        else if (self.position == THSidePositionRight)
        {
            make.left.mas_equalTo(CGRectGetWidth(self.displayFrame) - self.showAmount);
        }
    }];
    
    [_bottomSafeAreaView mas_updateConstraints:^(MASConstraintMaker *make) {
        if (self.position == THSidePositionTop)
        {
            make.height.mas_equalTo(0);
        }
        else if (self.position == THSidePositionLeft || self.position == THSidePositionRight)
        {
            make.width.mas_equalTo(self.showAmount);
        }
        else if (self.position == THSidePositionBottom)
        {
            make.height.mas_equalTo(MIN(self.showAmount, self.safeAreaInsetsBottom));
        }
    }];
}

- (void)setDisplayFrame:(CGRect)displayFrame
{
    if (!CGRectEqualToRect(displayFrame, _displayFrame))
    {
        _displayFrame = displayFrame;
        [self setNeedsUpdateConstraints];
        [self configContentSize];
    }
}

- (void)setDisplayView:(UIView *)displayView
{
     _displayView = displayView ?:[THCurrentVCWindowsManager shareManager].currentWindow;
}

- (void)setMaskerColor:(UIColor *)color
{
    _alphaView.backgroundColor = color;
}

- (void)tapRecgnized:(UITapGestureRecognizer *)gesture
{
    if (_enableTapGesture)
    {
        _hideByGesture = YES;
        [self hide:YES];
    }
}

- (CGRect)validFrameForDisplayViewDrag
{
    if (self.position == THSidePositionTop)
    {
        CGRect frame = self.displayFrame;
        frame.size.height = frame.size.height / 2.0f;
        return frame;
    }
    else if (self.position == THSidePositionBottom)
    {
        CGRect frame = self.displayFrame;
        frame.origin.y = frame.size.height / 2.0f;
        frame.size.height = frame.size.height / 2.0f;
        return frame;
    }
    else if (self.position == THSidePositionLeft)
    {
        CGRect frame = self.displayFrame;
        frame.size.width = frame.size.width / 2.0f;
        return frame;
    }
    else
    {
        CGRect frame = self.displayFrame;
        frame.origin.x = frame.size.width / 2.0f;
        frame.size.width = frame.size.width / 2.0f;
        return frame;
    }
}

- (CGRect)valideFrameForDrag
{
    CGFloat amount = _showAmount - HQSideDragRange;
    if (self.position == THSidePositionTop)
    {
        return CGRectMake(0, amount, self.width, self.height - amount);
    }
    else if (self.position == THSidePositionBottom)
    {
        return CGRectMake(0, 0, self.width, self.height - amount);
    }
    else if (self.position == THSidePositionLeft)
    {
        return CGRectMake(amount, 0, self.width - amount, self.height);
    }
    else
    {
        return CGRectMake(0, 0, self.width - amount, self.height);
    }
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
//    if (_screenID.length > 0)
//    {
//        BOOL result = [_screenID isEqualToString:[KScreenNavigator currentScreenID]];
//        if (!result)
//        {
//            self.canDragOut = NO;
//        }
//        return result;
//    }
    return YES;
}

- (BOOL)shouldDragOut
{
    if ([self.delegate respondsToSelector:@selector(shoundDragOutSideDragView:)])
    {
        return [self.delegate shoundDragOutSideDragView:self];
    }
    return YES;
}

- (void)displayViewPanRecgnized:(UIPanGestureRecognizer *)gesture
{
    if (gesture.state == UIGestureRecognizerStateBegan)
    {
        _enableDrag = [self shouldDragOut];
    }
    if (!_enableDrag)
    {
        return;
    }
    if (gesture.state == UIGestureRecognizerStateBegan || gesture.state == UIGestureRecognizerStateChanged)
    {
        if (!self.isDragging)
        {
            if (CGRectContainsPoint([self validFrameForDisplayViewDrag], [gesture locationInView:self.displayView]))
            {
                [gesture setTranslation:CGPointZero inView:self.displayView];
                _showAmount = 0;
                [self setupCustomizeView];
                self.dragging = YES;
            }
            else
            {
                [gesture setTranslation:CGPointZero inView:self.displayView];
            }
        }
        else
        {
            CGPoint translation = [gesture translationInView:self.displayView];
            CGFloat dragAmount = [self dragAmountWithTranslation:translation];
            if (dragAmount < 0)
            {
                _showAmount = 0;
                [gesture setTranslation:CGPointZero inView:self.displayView];
            }
            else if (dragAmount <= _contentAmount)
            {
                _showAmount = dragAmount;
            }
            else
            {
                _showAmount = _contentAmount + (dragAmount - _contentAmount) / 2;
            }
            [self showAmountChanged];
        }
    }
    else if (self.isDragging)
    {
        [self endDragging:[gesture velocityInView:self.displayView]];
    }
}

- (void)showAmountChanged
{
    [self updateShowAmountConstraints];
    _alphaView.alpha = _showAmount / _contentAmount;
    if ([self.delegate respondsToSelector:@selector(sideDragView:showAmountChanged:)])
    {
        if (self.position == THSidePositionBottom)
        {
            [self.delegate sideDragView:self showAmountChanged:_showAmount - self.safeAreaInsetsBottom];
        }
        else
        {
            [self.delegate sideDragView:self showAmountChanged:_showAmount];
        }
    }
}

- (void)endDragging:(CGPoint)velocity
{
    self.dragging = NO;
    if (_showAmount + [self velocityWithVelocity:velocity] > _contentAmount / 2)
    {
        [self show:YES];
    }
    else
    {
        _hideByGesture = YES;
        [self hide:YES];
    }
}

- (void)panRecgnized:(UIPanGestureRecognizer *)gesture
{
    if (!_enablePanGesture)
    {
        return;
    }
    if (gesture.state == UIGestureRecognizerStateBegan || gesture.state == UIGestureRecognizerStateChanged)
    {
        CGPoint point = [gesture locationInView:self];
        if (!self.isDragging)
        {
            if (CGRectContainsPoint([self valideFrameForDrag], point))
            {
                [self startDraggingAtPoint:point];
            }
            else
            {
                [gesture setTranslation:CGPointZero inView:self];
            }
        }
        else
        {
            CGPoint translation = [gesture translationInView:self];
            CGFloat dragAmount = [self dragAmountWithTranslation:translation];
            if (dragAmount > 0)
            {
                CGFloat screenAmount = (self.position == THSidePositionLeft || self.position == THSidePositionRight) ? self.width : self.height;
                CGFloat leftAmount = screenAmount - _contentAmount - _dragStartDistance;
                if (leftAmount > 0)
                {
                    CGFloat scaleFactor = (screenAmount - _contentAmount) * 0.5 / leftAmount;
                    _showAmount = _contentAmount + dragAmount * scaleFactor;
                }
            }
            else
            {
                if (_dragStartDistance <= 0)
                {
                    _showAmount = _contentAmount + dragAmount;
                }
                else
                {
                    CGFloat currentDistance = [self distanceOfTouch:point showAmount:_showAmount];
                    if (currentDistance <= 0)
                    {
                        CGPoint newTranslation = [self translationAtPoint:point];
                        [gesture setTranslation:newTranslation inView:self];
                        _dragStartDistance = 0;
                        _showAmount = _contentAmount + [self dragAmountWithTranslation:newTranslation];
                    }
                    else if (_showAmount <= _contentAmount)
                    {
                        [gesture setTranslation:CGPointZero inView:self];
                        [self startDraggingAtPoint:point];
                        _showAmount = _contentAmount;
                    }
                    else
                    {
                        _showAmount = _contentAmount + dragAmount / 2;
                    }
                }
            }
            [self showAmountChanged];
        }
    }
    else if (self.isDragging)
    {
        [self endDragging:[gesture velocityInView:self]];
    }
}

- (CGPoint)translationAtPoint:(CGPoint)point
{
    if (self.position == THSidePositionTop)
    {
        return CGPointMake(0, point.y - _contentAmount);
    }
    if (self.position == THSidePositionBottom)
    {
        return CGPointMake(0, point.y - (CGRectGetHeight(self.displayFrame) - _contentAmount));
    }
    if (self.position == THSidePositionLeft)
    {
        return CGPointMake(point.x - _contentAmount, 0);
    }
    return CGPointMake(point.x - (CGRectGetWidth(self.displayFrame) - _contentAmount), 0);
}

- (void)startDraggingAtPoint:(CGPoint)point
{
    _dragging = YES;
    _dragStartDistance = [self distanceOfTouch:point showAmount:_showAmount];
}

- (CGFloat)dragAmountWithTranslation:(CGPoint)translation
{
    if (self.position == THSidePositionTop)
    {
        return translation.y;
    }
    if (self.position == THSidePositionBottom)
    {
        return -translation.y;
    }
    if (self.position == THSidePositionLeft)
    {
        return translation.x;
    }
    return -translation.x;
}

- (CGFloat)distanceOfTouch:(CGPoint)point showAmount:(CGFloat)showAmount
{
    if (self.position == THSidePositionTop)
    {
        return point.y - showAmount;
    }
    if (self.position == THSidePositionBottom)
    {
        return (self.height - point.y) - showAmount;
    }
    if (self.position == THSidePositionLeft)
    {
        return point.x - showAmount;
    }
    return (self.width - point.x) - showAmount;
}

- (CGFloat)velocityWithVelocity:(CGPoint)velocity
{
    if (self.position == THSidePositionTop)
    {
        return velocity.y;
    }
    if (self.position == THSidePositionBottom)
    {
        return -velocity.y;
    }
    if (self.position == THSidePositionLeft)
    {
        return velocity.x;
    }
    return -velocity.x;
}

- (void)setupCustomizeView
{
    [self configContentSize];
    if (_customizeView.superview != self.contentView)
    {
        [self.contentView addSubview:_customizeView];
    }
    [self updateCustomeViewConstraints];
    if (self.superview != self.displayView)
    {
        self.frame = self.displayFrame;
         [self.displayView addSubview:self];
        [self mas_updateConstraints:^(MASConstraintMaker *make) {
//            make.edges.equalTo(0);
            make.left.mas_equalTo(self.displayFrame.origin.x);
            make.top.mas_equalTo(self.displayFrame.origin.y);
            make.width.mas_equalTo(CGRectGetWidth(self.displayFrame));
            make.height.mas_equalTo(CGRectGetHeight(self.displayFrame));
        }];
        [self setNeedsUpdateConstraints];
        [self layoutIfNeeded];
    }
}

- (void)showInView:(UIView *)view animated:(BOOL)animated
{
    if (view != nil)
    {
        _displayView = view;
    }
    [self show:animated];
}

- (void)show:(BOOL)animated
{
    [self setupCustomizeView];
    _showAmount = _contentAmount;
    if (animated)
    {
        if (self.disableSpringAnimation)
        {
            [UIView animateWithDuration:.25 animations:^{
                [self showAmountChanged];
                [self layoutIfNeeded];
            } completion:^(BOOL finished) {
                [self didShow];
            }];
        }
        else
        {
            [UIView animateWithDuration:.5 delay:0 usingSpringWithDamping:.66 initialSpringVelocity:.5 options:UIViewAnimationOptionCurveEaseOut animations:^{
                [self showAmountChanged];
                [self layoutIfNeeded];
            } completion:^(BOOL finished) {
                [self didShow];
            }];
        }
    }
    else
    {
        [self showAmountChanged];
        [self layoutIfNeeded];
        [self didShow];
    }
}

- (void)refreshDisplay:(BOOL)animated
{
    if (self.showAmount > 0)
    {
        [self show:animated];
    }
}

- (void)hide:(BOOL)animated
{
    _showAmount = 0;
    if (animated)
    {
        @weakify(self);
        [UIView animateWithDuration:.2 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
            [self showAmountChanged];
            [self layoutIfNeeded];
        } completion:^(BOOL finished) {
            @strongify(self);
            [self didHide];
        }];
    }
    else
    {
        [self showAmountChanged];
        [self layoutIfNeeded];
        [self didHide];
    }
}

- (BOOL)isDisplay
{
    return self.superview != nil && _showAmount > 0;
}

- (void)didShow
{
    if ([self.delegate respondsToSelector:@selector(sideDragViewDidShow:)])
    {
        [self.delegate sideDragViewDidShow:self];
    }
}

- (void)didHide
{
    if ([self.delegate respondsToSelector:@selector(sideDragViewDidHide:)])
    {
        [self.delegate sideDragViewDidHide:self];
    }
    if ([self.delegate respondsToSelector:@selector(sideDragViewDidHide:causedByGesture:)])
    {
        [self.delegate sideDragViewDidHide:self causedByGesture:_hideByGesture];
    }
    _hideByGesture = NO;
    [_customizeView removeFromSuperview];
    [self removeFromSuperview];
}

- (void)setHeaderCornerRadius:(CGFloat)radius
{
    if (radius > 0 && _blurView.isHidden)
    {
        CGRect frame = self.displayFrame;
        frame.origin = CGPointZero;
        
        UIRectCorner corners;
        if (self.position == THSidePositionBottom)
        {
            corners = UIRectCornerTopLeft | UIRectCornerTopRight;
        }
        else if (self.position == THSidePositionTop)
        {
            corners = UIRectCornerBottomLeft | UIRectCornerBottomRight;
        }
        else if (self.position == THSidePositionLeft)
        {
            corners = UIRectCornerBottomRight | UIRectCornerTopRight;
        }
        else
        {
            corners = UIRectCornerTopLeft | UIRectCornerBottomLeft;
        }
        
        [THBaseUtil checkAndRoundCornerToView:_contentView rect:frame corners:corners radius:radius];
        _contentView.clipsToBounds = YES;
    }
    else
    {
        _contentView.layer.mask = nil;
    }
}

- (void)dealloc
{
    self.canDragOut = NO;
}


@end
